package com.holly.unit.bpmn.modular.activiti.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.holly.unit.bpmn.activiti.ActivitiOperator;
import com.holly.unit.bpmn.activiti.entity.ActivitiZProcess;
import com.holly.unit.bpmn.activiti.exception.BpmnActivitiException;
import com.holly.unit.bpmn.activiti.pojo.*;
import com.holly.unit.bpmn.activiti.util.ActUtil;
import com.holly.unit.core.pojo.response.ErrorResponseData;
import com.holly.unit.core.pojo.response.ResponseData;
import com.holly.unit.core.pojo.response.SuccessResponseData;
import com.holly.unit.db.api.pojo.page.PageResult;
import com.holly.unit.scanner.api.annotation.ApiResource;
import com.holly.unit.scanner.api.annotation.GetResource;
import com.holly.unit.scanner.api.annotation.PostResource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类描述: 流程定义控制器
 *
 * @author fxr
 * @version 1.0.0
 * @date 2022/2/21 18:52
 */
@RestController
@ApiResource(name = "流程定义相关API")
@Api(tags = "流程定义相关API")
@Slf4j
public class ActivitProcessDefController {

    @Resource
    private ActivitiOperator operator;

    @ApiOperation("流程定义列表")
    @GetResource(name = "流程定义列表", path = "/processDef/listData")
    public ResponseData listData(HttpServletRequest request) {
        String lcmc = StrUtil.nullToDefault(request.getParameter("lcmc"),"");
        String lckey = StrUtil.nullToDefault(request.getParameter("lckey"),"");
        String zx = StrUtil.nullToDefault(request.getParameter("zx"),"");
        String status = StrUtil.nullToDefault(request.getParameter("status"),"");
        String appId = StrUtil.nullToDefault(request.getHeader("App-Id"),"");
        String pageNo = StrUtil.nullToDefault(request.getParameter("pageNo"),"");
        String pageSize = StrUtil.nullToDefault(request.getParameter("pageSize"),"");
        Map<String,Object> params = new HashMap<>();
        params.put("lcmc",lcmc);
        params.put("lckey",lckey);
        params.put("zx",zx);
        params.put("status",status);
        params.put("appId",appId);
        params.put("pageNo",Integer.parseInt(pageNo));
        params.put("pageSize",Integer.parseInt(pageSize));
        PageResult<ActProcessRequest> activitiZProcesses = operator.listData(params);
        return new SuccessResponseData(activitiZProcesses);
    }

    @ApiOperation("激活或挂起流程定义")
    @PostResource(name = "激活或挂起流程定义", path = "/processDef/updateStatus")
    public ResponseData updateStatus(@RequestBody @Validated(ProcessDefActOrSuspendRequest.actOrSusStatus.class) ProcessDefActOrSuspendRequest request) {
        String id = request.getId();
        Integer status = request.getStatus();
        try {
            operator.activateOrSuspend(id,status);
            return new SuccessResponseData();
        } catch (BpmnActivitiException e) {
            e.printStackTrace();
            return new ErrorResponseData("holly-d-bpmn","未设置关联表单，点击编辑设置。");
        }

    }

    @ApiOperation("通过id删除流程定义")
    @PostResource(name = "通过id删除流程定义", path = "/processDef/delByIds")
    public ResponseData delByIds(@RequestBody @Validated(ProcessDefDelEntityRequest.delActDefEntityById.class)ProcessDefDelEntityRequest request) {
        String ids = request.getIds();
        boolean flag = operator.delByIds(ids);
        if (flag) {
            return new SuccessResponseData();
        } else {
            return new ErrorResponseData("holly-d-bpmn","包含已发起申请的流程，无法删除或该数据已删除！");
        }

    }

    @ApiOperation("流程定义转化为流程模型")
    @PostResource(name = "流程定义转化为流程模型", path = "/processDef/convertToModel")
    public ResponseData convertToModel( @RequestBody @Validated(ProcessDefModelRequest.convertToModelById.class)ProcessDefModelRequest request) {
        try {
            String id = request.getId();
            operator.convertToModel(id);
            return new SuccessResponseData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ErrorResponseData("holly-d-bpmn","流程定义转化为流程模型失败");
    }

    @ApiOperation("流程定义修改")
    @PostResource(name = "流程定义修改", path = "/processDef/updateInfo")
    public ResponseData updateInfo(@RequestBody ProcessDefEditEntityRequest request) {
        ActivitiZProcess actProcess = new ActivitiZProcess();
        BeanUtil.copyProperties(request,actProcess,false);
        boolean b = operator.updateZProcess(actProcess);
        if (b) {
            return new SuccessResponseData();
        } else {
            return new ErrorResponseData("holly-d-bpmn","流程定义修改失败");
        }
    }

    @ApiOperation("通过流程定义id获取流程节点")
    @PostResource(name = "通过流程定义id获取流程节点", path = "/processDef/getProcessNode")
    public ResponseData getProcessNode(@RequestBody @Validated(ProcessDefGetNodeRequest.getProcessNodeById.class) ProcessDefGetNodeRequest request) {
        List<ProcessNode> processNodes = operator.fetchProcessNode(request.getId());
        return new SuccessResponseData(processNodes);
    }

    @ApiOperation("编辑节点分配用户")
    @PostResource(name = "编辑节点分配用户", path = "/processDef/editNodeUser")
    public ResponseData editNodeUser(@RequestBody ProcessDefEditNodeUserRequest request) {
        try {
            String nodeId = request.getNodeId();
            String roleIds = request.getRoleIds();
            String userIds = request.getUserIds();
            String departmentIds = request.getDepartmentIds();
            Boolean chooseDepHeader = request.getChooseDepHeader();
            Boolean chooseSponsor = request.getChooseSponsor();
            operator.editNodeUser(nodeId,userIds,roleIds,departmentIds,chooseDepHeader,chooseSponsor);
            return new SuccessResponseData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ErrorResponseData("holly-d-bpmn","编辑节点分配用户失败");
    }

    @ApiOperation(value = "通过当前节点定义id获取下一个节点")
    @GetResource(name = "通过当前节点定义id获取下一个节点", path = "/processDef/getNextNode")
    public ResponseData getNextNode(@ApiParam("当前节点定义id")  String procDefId,
                              @ApiParam("当前节点定义id")  String currActId,
                              @ApiParam("当前流程实例id") String procInsId,@ApiParam("当前执行实例id")String executionId,
                              @ApiParam("表单表名") String tableName,@ApiParam("表单数据主键")String tableId
                        ) {

        ProcessNode processNode = operator.fetchNextNode2(procDefId, currActId, procInsId,tableId,tableName,executionId);



        return new SuccessResponseData(processNode);
    }

    @ApiOperation(value = "通过节点nodeId获取审批人")
    @GetResource(name = "通过节点nodeId获取审批人", path = "/processDef/getNode/{nodeId}")
    public ResponseData getNode(@ApiParam("节点nodeId") @PathVariable String nodeId) {
        ProcessNode processNode = operator.fetchNode(nodeId);
        return new SuccessResponseData(processNode);
    }

    @ApiOperation(value = "通过流程定义id获取第一个任务节点")
    @GetResource(name = "通过流程定义id获取第一个任务节点", path = "/processDef/getFirstNode")
    public ResponseData getFirstNode(@Validated(ProcessDefGetFirstNodeRequest.getFirstNode.class)ProcessDefGetFirstNodeRequest request) {
        String procDefId = request.getProcDefId();
        String key = request.getKey();
        String value = request.getValue();
//        // 天数小于1
//        key ="days";
//        value="1";
        ProcessNode processNode = operator.getFirstNode(procDefId,key,value);
        return new SuccessResponseData(processNode);
    }

    @ApiOperation(value = "通过流程定义id获取第一个任务节点")
    @GetResource(name = "通过流程定义id获取第一个任务节点", path = "/processDef/getFirstTaskNode")
    public ResponseData getFirstTaskNode(@Validated(ProcessDefGetFirstNodeRequest.getFirstNode.class)ProcessDefGetFirstNodeRequest request) {
        String procDefId = request.getProcDefId();
        String tableId = request.getTableId();
        String tableName = request.getTableName();
        ProcessNode processNode = operator.getFirstTaskNode(procDefId,tableId,tableName);
        return new SuccessResponseData(processNode);
    }

    @ApiOperation(value = "流程定义条件表达式")
    @PostResource(name = "流程定义条件表达式", path = "/processDef/setEl")
    public ResponseData setEl(@RequestBody @Validated(ProcessDefSetElRequest.checkEl.class)ProcessDefSetElRequest request) {

        String modelId = request.getModelId();
        String nodeId = request.getNodeId();
        List<ActiviExpressionRequest> requests = request.getRequests();
        try {
            ActUtil.setSequenceFlowCondition(modelId,nodeId,requests);
        } catch (IOException e) {
            return new ErrorResponseData("95008",e.getMessage());
        }
        return new SuccessResponseData();
    }

    @ApiOperation("创建事件监听")
    @PostResource(name = "创建事件监听", path = "/processDef/createEventListener")
    public ResponseData createEventListener(@RequestBody @Validated(CreateEventListenerRequest.createEventListener.class) CreateEventListenerRequest request) {

        String modelId = request.getModelId();
        String nodelId = request.getNodeId();
        String eventType = request.getEventType();
        String classUrl = request.getClassUrl();
        String listenerType = request.getListenerType();
        try {
            ActUtil.createWorkFlowListener(modelId,nodelId,listenerType,eventType,classUrl);
        } catch (IOException e) {
            return new ErrorResponseData("95009",e.getMessage());
        }
        return new SuccessResponseData();
    }




}
